package hibernatemock;

import java.lang.annotation.Annotation;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

import com.rits.cloning.Cloner;

public class Setup {

	@Setter private Object instance;
	@Setter @Getter private Class<?> clazzField;
	@Setter @Getter private Class<?> clazzAnnotation;
	@Getter private Integer deliveryCount = 0;
	static private Cloner cloner = new Cloner();

	public Setup(){
		
	}
	
	public Setup(Class<?> clazzField) {
		this.clazzField = clazzField;
	}

	public Setup(Class<?> clazzField, Class<?> clazzAnnotation) {
		this.clazzField = clazzField;
		this.clazzAnnotation = clazzAnnotation;
	}

	public Object getInstance(List<Annotation> fieldAnnotations) {
		if (instance instanceof FieldHandler) {
			FieldHandler fieldHandler = (FieldHandler) instance;
			for (Annotation annotation : fieldAnnotations)
				if (annotation.annotationType() == clazzAnnotation) {
					return cloner.deepClone(fieldHandler.deliver(annotation));
				}
		}
		return cloner.deepClone(instance);
	}

	public void addDelivery() {
		deliveryCount++;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((clazzAnnotation == null) ? 0 : clazzAnnotation.hashCode());
		result = prime * result + ((clazzField == null) ? 0 : clazzField.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Setup other = (Setup) obj;
		if (clazzAnnotation == null) {
			if (other.clazzAnnotation != null)
				return false;
		} else if (!clazzAnnotation.equals(other.clazzAnnotation))
			return false;
		if (clazzField == null) {
			if (other.clazzField != null)
				return false;
		} else if (!clazzField.equals(other.clazzField))
			return false;
		return true;
	}

}
